package model;

public class TrianglePixelization {
	private IPixelizationListener listener=new DummyPixelizationListener(); 
	public float sizeOfPixelCube=0.1f;
	// this approach could be too sensitive to presentation of the 3D model;
	// for the same thing, because of accuracy is different, they are consider not the same;  
	public void doPixelization2D(RoffTriangle triangle){
		//simpleMethod(triangle);
		RoffVector3D p1=triangle.getPoint1();
		RoffVector3D p2=triangle.getPoint2();
		RoffVector3D p3=triangle.getPoint3();
		doRefine(p1.x,p1.y,p1.z,p2.x,p2.y,p2.z,p3.x,p3.y,p3.z); 
	}
	public void simpleMethod(RoffTriangle triangle){
		listener.informs(triangle.getPoint1().x, triangle.getPoint1().y , triangle.getPoint1().z,2 );
		listener.informs(triangle.getPoint2().x, triangle.getPoint2().y , triangle.getPoint2().z,2 );
		listener.informs(triangle.getPoint3().x, triangle.getPoint3().y , triangle.getPoint3().z,2 );
		listener.informs(triangle.getCentroid().x, triangle.getCentroid().y , triangle.getCentroid().z,1);
	}
	public IPixelizationListener getListener() {
		return listener;
	}
	public void setListener(IPixelizationListener listener) {
		this.listener = listener;
	}
	public void doRefine(double x1,double y1, double z1,
			double x2, double y2, double z2,
			double x3, double y3, double z3
			){
		double l12=abs(x1-x2)+abs(y1-y2)+abs(z1-z2);
		double l13=abs(x1-x3)+abs(y1-y3)+abs(z1-z3); 
		double l23=abs(x2-x3)+abs(y2-y3)+abs(z2-z3);
		double d=max(l12,l13,l23); 
		if (d<sizeOfPixelCube){
			listener.informs((x1+x2+x3)/3, (y1+y2+y3)/3, (z1+z2+z3)/3, 1); 
			return ; 
		}else {
			// construct 4 more triangles; 
			double xm_12=(x1+x2)/2;  
			double ym_12=(y1+y2)/2;
			double zm_12=(z1+z2)/2;
			double xm_13=(x1+x3)/2;  
			double ym_13=(y1+y3)/2;
			double zm_13=(z1+z3)/2;
			double xm_23=(x2+x3)/2;  
			double ym_23=(y2+y3)/2;
			double zm_23=(z2+z3)/2;
			doRefine(x1,y1,z1,xm_12,ym_12,zm_12,xm_13,ym_13,zm_13);
			doRefine(x2,y2,z2,xm_12,ym_12,zm_12,xm_23,ym_23,zm_23);
			doRefine(x3,y3,z3,xm_13,ym_13,zm_13,xm_23,ym_23,zm_23);
			doRefine(xm_12,ym_12,zm_12,xm_13,ym_13,zm_13,xm_23,ym_23,zm_23);
		}
	}
	public static double max(double x, double y, double z){
		return Math.max(Math.max(x, y),z); 
	}
	public static double abs(double x){
		return x>0?x:-x; 
	}
}
